package zzcltw.com.util;

import javax.crypto.*;

import org.apache.log4j.Logger;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

public class EncryptUtil {
	private static final String ALGORITHM = "DES";
	private static final String HASH_ALGORITHM_NAME = "md5";
	private static final int HASH_ITERATIONS = 2;
	private EncryptUtil(){}
	private static final Logger LOGGER = Logger.getLogger ( DateUtil.class.getName () );
	public static Map<String, String> encrypt(String username, String password) {
		String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
		SimpleHash hash = new SimpleHash(HASH_ALGORITHM_NAME, password, username + salt, HASH_ITERATIONS);
		String encodedPassword = hash.toHex();
		Map<String, String> encryptMap = new HashMap<>();
		encryptMap.put("loginCertifCrkey", salt);
		encryptMap.put("userLoginPw", encodedPassword);
		return encryptMap;
	}

	public static Map<String, String> encrypt(String username, String password, String salt) {
		SimpleHash hash = new SimpleHash(HASH_ALGORITHM_NAME, password, username + salt, HASH_ITERATIONS);
		String encodedPassword = hash.toHex();
		Map<String, String> encryptMap = new HashMap<>();
		encryptMap.put("loginCertifCrkey", salt);
		encryptMap.put("userLoginPw", encodedPassword);
		return encryptMap;
	}
	

	/**
	 * Get Des Key
	 */
	public static byte[] getKey() throws Exception {
		KeyGenerator keygen = null;
		try {
			keygen = KeyGenerator.getInstance(ALGORITHM);
			SecretKey deskey = keygen.generateKey();
			
			return deskey.getEncoded();
		} catch (Exception e) {
			LOGGER.info("************",e);
		}
		
		return new byte[0];
	}
	/**
	 * Encrypt DES加密
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 */
	public static byte[] encode(byte[] input, byte[] key) throws Exception, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		SecretKey deskey = new javax.crypto.spec.SecretKeySpec(key, ALGORITHM);
		Cipher c1 = Cipher.getInstance(ALGORITHM);
		c1.init(Cipher.ENCRYPT_MODE, deskey);
		return c1.doFinal(input);
	}
	/**
	 * Decrypt DES解密
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 */
	public static byte[] decode(byte[] input, byte[] key) throws Exception, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		SecretKey deskey = new javax.crypto.spec.SecretKeySpec(key, ALGORITHM);
		Cipher c1 = Cipher.getInstance(ALGORITHM);
		c1.init(Cipher.DECRYPT_MODE, deskey);
		return c1.doFinal(input);
	}
	/**
	    * 进行MD5加密
	    * @param info 要加密的信息
	    * @return String 加密后的字符串
	    */
	    public static String encryptToMD5(String info) {
	        byte[] digesta = null;

	        try {
	            // 得到一个md5的消息摘要
	            MessageDigest alga = MessageDigest.getInstance("MD5");
	            // 添加要进行计算摘要的信息
	            alga.update(info.getBytes());
	            // 得到该摘要
	            digesta = alga.digest();
	        } catch (NoSuchAlgorithmException e) {
	        	LOGGER.info("************",e);
	        }

	        // 将摘要转为字符串
	        String rs = byte2hex(digesta);

	        return rs;
	    }
	/**
    * 将二进制转化为16进制字符串
    * @param b 二进制字节数组
    * @return String
    */
    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp;

        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));

            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }

        return hs.toUpperCase();
    }
    /**
	 * Convert String to byte[]
	 */
	public static byte[] hex2byte(String hex) throws IllegalArgumentException {
		if (hex.length() % 2 != 0) {
			throw new IllegalArgumentException();
		}
		char[] arr = hex.toCharArray();
		byte[] b = new byte[hex.length() / 2];
		for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
			String swap = "" + arr[i++] + arr[i];
			int byteint = Integer.parseInt(swap, 16) & 0xFF;
			b[j] = new Integer(byteint).byteValue();
		}
		return b;
	}
	public static String paswEncry(String psw) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, Exception{
		String channel = "zzclt";
		String key = "A0D3F089F59D4A8391AF04638971B199";		
		String cid = EncryptUtil.byte2hex(EncryptUtil.encode(psw.getBytes(), "zzcltgsw".getBytes()));
		String str = new String(EncryptUtil.decode(EncryptUtil.hex2byte(cid), "zzcltgsw".getBytes()));
		StringBuilder mdSign = new StringBuilder();
		mdSign.append(str).append(channel).append(key);
		String signEncode = EncryptUtil.encryptToMD5(mdSign.toString());
		return signEncode;
	}
	public static void main(String[] args) throws Exception, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		String channel = "zzclt";
		String key = "A0D3F089F59D4A8391AF04638971B199";		
		String cid = EncryptUtil.byte2hex(EncryptUtil.encode("123456".getBytes(), "zzcltgsw".getBytes()));
		//String sign = EncryptUtil.encryptToMD5(cid + channel + key);
		String sign = EncryptUtil.encryptToMD5(cid + channel + key);
		//003CD8FD1CA1CD4F8444DBC651049A54
		System.err.println("cid=" + cid);
		String str = new String(EncryptUtil.decode(EncryptUtil.hex2byte(cid), "zzcltgsw".getBytes()));
		StringBuilder mdSign = new StringBuilder();
		mdSign.append(cid).append(channel).append(key);
		String signEncode = EncryptUtil.encryptToMD5(mdSign.toString());
		System.err.println("str=" + str);
		System.err.println("sign=" + sign);
		System.err.println("signEncode="+signEncode);
		Map<String,String> map = encrypt("张小明","123456");
		Map<String,String> map1 = encrypt("zzclt","zzclt123");
		//Map<String,String> map1 = encrypt("张小明","123456","7803ba5c8c9faddebfeb17dcef5934de");
		//7803ba5c8c9faddebfeb17dcef5934de
		//17aedfe5af04067b77a9b4c4dd1ddb9d  1f285e30e0d450590718974c128e6c21
		//94429fa278941c433d06c78a9ab22825
		//System.err.println("*****"+map.toString());
		System.err.println("*****"+map.toString());
		AesCipherService aesCipherService = new AesCipherService();

		aesCipherService.setKeySize(128); //设置key长度
		//Key key = aesCipherService.generateNewKey();
		String text = "helloworld";
		//加密
		//String encText = aesCipherService.encrypt(text.getBytes(), key.getEncoded()).toHex();
		//String encText1 = aesCipherService.encrypt(text.getBytes(), key.getEncoded()).toHex();
		//System.out.println("encText:"+encText);
		//System.out.println("encText1:"+encText1);
		//解密
		//String decText =
		//new String(aesCipherService.decrypt(Hex.decode(encText), key.getEncoded()).getBytes());
		//System.out.println("decText:"+decText);
	}
}
